﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//结构体
//创建结构体:struct + 结构体名
struct Stu
{
	//结构体成员
	char name[20];//名字
	char sex[5];//性别
	int age;//年龄
	char id[10];//学号
}stu1,stu2;//变量列表（全局变量）

//创建结构体变量（全局变量）
struct Stu stu3;
int main()
{
	//创建结构体变量并顺序初始化（局部变量）
	struct Stu stu4 = { "zhangsan","男",20,"2021011456" };
	//创建变量并以指定顺序初始化
	struct Stu stu5 = { .age = 18,.name = "cuihua",.sex = "女" };
	//结构体变量访问: 变量名 + .(操作符)+成员名
	printf("%s\n", stu4.name);
	printf("%d\n", stu4.age);
	printf("%s\n", stu5.sex);
	return 0;
}

//结构体内存对齐
//对齐规则：
//1.结构体的第一个成员对齐到和结构体变量偏移量为0的地址处（即结构体变量申请内存空间的起始地址处）
//2.从第二个成员开始对齐到某个“对齐数”的整数倍的地址处。
/*对齐数=编译器默认的一个对齐数与该成员变量所占内存空间大小的较小值（vs编译器默认对齐数为8）*/
//3.结构体总大小为最大对齐数的整数倍（结构体成员变量都有一个对齐数，所有对齐数中最大的就是最大对齐数）
//4.如果嵌套了结构体的情况，嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处，结构体的整体⼤⼩就是所有最⼤对⻬数（含嵌套结构体中成员的对⻬数）的整数倍。
struct s1
{
	char a;
	int b;
	char c;
};

struct s2
{
	char x;
	char z;
	int y;
};

struct s3
{
	double a;
	char b;
	int c;
};

struct s4
{
	char x;
	struct s3 y;
	double z;
};

int main()
{
	printf("%zu\n", sizeof(struct s1));
	printf("%zu\n", sizeof(struct s2));
	printf("%zu\n", sizeof(struct s3));
	printf("%zu\n", sizeof(struct s4));
	return 0;
}

//修改默认对齐数：#pragma pack(n), 即设置对齐数为n。
#pragma pack(1)
struct s1
{
	char a;
	char b;
	int c;
}x;
#pragma pack() //取消设置的对齐数，恢复默认值
struct s2
{
	char a;
	char b;
	int c;
}y;
int main()
{
	printf("%zu\n", sizeof(x));
	printf("%zu\n", sizeof(y));
	return 0;
}


//结构体传参
struct S
{
	int arr[20];
	int num;
	char ch;
};

 struct S s1= { {1,2,3,4,5},20,'a'};
 size_t sz = sizeof(s1.arr)/sizeof(s1.arr[0]);
void print1(struct S a,int sz)
{
	printf("%d\n", a.num);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", a.arr[i]);
	}
	printf("\n");
}
void print2(struct S* pf,int sz)
{
	printf("%d\n", pf->num);
	int j = 0;
	for (j = 0; j < sz; j++)
	{
		printf("%d ", pf->arr[j]);
	}
	printf("\n");
}
int main()
{
	print1(s1,sz);
	print2(&s1,sz);//传结构体变量s1的地址
	printf("sz = %d\n", sz);
	return 0;
}